package com.bps.zzant.json;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.bps.zzant.model.ArtFile;
import com.bps.zzant.model.FileMeta;
import com.bps.zzant.services.CustomerService;
import com.bps.zzant.services.FileService;

@Controller
public class FileJSON {
	private static final Logger logger = LoggerFactory.getLogger(FileJSON.class);
	

	
	@Autowired
	private FileService fileService;
	
	@RequestMapping(value = "fileUpload.json", method = RequestMethod.POST)
	public @ResponseBody LinkedList<ArtFile> fileUpload(MultipartHttpServletRequest request, HttpServletResponse response){
		
		LinkedList<ArtFile>  files = new LinkedList<ArtFile>();
		ArtFile artFile = null;
		
		int customerId = Integer.parseInt((String)request.getParameter("customerId"));
		int orderId = Integer.parseInt((String)request.getParameter("orderId"));
		String artFileType = (String)request.getParameter("fileType");
		String inkNotes = (String)request.getParameter("inkNotes");
		
		logger.info(" +++++++in UploadFileController.uploadFile. the customeId: " + customerId);
		logger.info(" +++++++in UploadFileController.uploadFile. the orderId: " + orderId);
		logger.info(" +++++++in UploadFileController.uploadFile. the fileType: " + artFileType);
		logger.info(" +++++++in UploadFileController.uploadFile. the inkNotes: " + inkNotes);
		
		
	    Map<String, Object> map = new HashMap<String, Object>(); 
        //1. build an iterator
        Iterator<String> itr =  request.getFileNames();
        MultipartFile mpf = null;

        //2. get each file
        while(itr.hasNext()){

            //2.1 get next MultipartFile
            mpf = request.getFile(itr.next()); 
            logger.info(mpf.getOriginalFilename() +" uploaded! "+files.size());

            //2.2 if files > 10 remove the first from the list
           //  if(files.size() >= 10)
              //   files.pop();


            String fileDir = "C:/zzant_files/"+customerId+"/"+orderId+"/";
            
            //2.3 create new fileMeta
            artFile = new ArtFile();
            artFile.setFileName(mpf.getOriginalFilename());
            // artFile.setFileSize(mpf.getSize()/1024+" Kb");
            artFile.setFileType(artFileType);
            artFile.setFileDir(fileDir);
            artFile.setInkNotes(inkNotes);
            
            try {
            	//make the dir if not exist
            	FileUtils.forceMkdir(new File(fileDir));
               
            	
               
                // copy file to local disk (make sure the path "e.g. D:/temp/files" exists)            
                FileCopyUtils.copy(mpf.getBytes(), new FileOutputStream(fileDir + mpf.getOriginalFilename()));
                
                artFile = new ArtFile(customerId, orderId, artFileType, fileDir, mpf.getOriginalFilename(), inkNotes);
                fileService.saveFile(artFile);
                
                artFile.setBytes(mpf.getBytes());
                
           } catch (IOException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
           }
            //2.4 add to files
            files.add(artFile);
        }
       // result will be like this
       // [{"fileName":"app_engine-85x77.png","fileSize":"8 Kb","fileType":"image/png"},...]
       return files;

		
		
		
	}
	
	@RequestMapping(value = "/getFile/{value}", method = RequestMethod.GET)
    public void getFile(HttpServletResponse response,@PathVariable String value){
        
		
		logger.info(" +++++++in UploadFileController.getFile:" + value );
		
		ArtFile artFile = fileService.getFileById(Integer.parseInt(value));
		
		 File file = new File(artFile.getFileDir()+artFile.getFileName());

        try {      
               response.setContentType(artFile.getFileType());
               response.setHeader("Content-disposition", "attachment; filename=\""+artFile.getFileName()+"\"");
               FileCopyUtils.copy(FileUtils.readFileToByteArray(file), response.getOutputStream());
        }catch (IOException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
        }
    }
	
	@RequestMapping(value = "/removeFile.json/{fileId}/{orderId}", method = RequestMethod.POST)
    public Map removeFile(HttpServletResponse response,@PathVariable int fileId, @PathVariable int orderId){
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("success", new Boolean("true"));
		
		logger.info(" +++++++in UploadFileController.removeFile:" + fileId + ". order id: " + orderId );
		try {
			//remove database entry
			ArtFile artFile = fileService.getFileById(fileId);
			fileService.deleteFile(artFile);
			
			//remove the physical file on the drive  - not remove at this point because in case of duplicate entries, and delete one entry, 
			// will cause the program crash because the 2nd entry cannot find the file.
			
			// File file = new File(artFile.getFileDir()+artFile.getFileName());			
			// FileUtils.deleteQuietly(file);
		} catch (Exception e) {
			map.put("success", new Boolean("true"));
			logger.info(" +++++++in UploadFileController.removeFile:" + e.getLocalizedMessage());
		}
		
		return map;
		
    }
	
}
